package com.gmail.dengtao.joe.group.interceptor;

import com.gmail.dengtao.joe.group.channel.Channel;
import com.gmail.dengtao.joe.group.member.IdleStatus;
import com.gmail.dengtao.joe.group.member.Member;
import com.gmail.dengtao.joe.transport.handler.Handler;

/**
 * A interceptor which intercepts {@link Handler}  events.
 * Interceptors can be used for these purposes:
 * <ul>
 *   <li>Event logging,</li>
 *   <li>Performance measurement,</li>
 *   <li>Authorization,</li>
 *   <li>Overload control,</li>
 *   <li>Message transformation (e.g. encryption and decryption, ...),</li>
 *   <li>and many more.</li>
 * </ul>
 * <p>
 * <strong>You can implement your interceptors to intercept message you recived.</strong>
 *
 * <h3>The Life Cycle</h3>
 * {@link Interceptor}s are activated only when they are inside {@link InterceptorStack}.
 * <p>
 * @author <a href="mailto:joe.dengtao@gmail.com">DengTao</a>
 * @version 1.0
 * @since 1.0
 */
public interface Interceptor {

	/**
     * Invoked by {@link InterceptorStack} when this interceptor
     * is added to a {@link InterceptorStack} at the first time, so you can
     * initialize shared resources.
     */
    void init();

    /**
     * Invoked by {@link InterceptorStack} when this interceptor
     * is not used by any {@link InterceptorStack} anymore, so you can destroy
     * shared resources.
     */
    void destroy();
	
	/**
     * A member was added to the group
	 * @param nextEntity 
     * @param member Member - the member that was added
	 * @since 1.0
	 */
    public void memberAdded(InterceptorEntity nextEntity, Channel channel, Member member) throws Exception;

	/**
     * A member was removed from the group
     * @param member Member - the member that was removed
     * @since 1.0
     */
	void memberDisappeared(InterceptorEntity nextEntity, Channel channel, Member member) throws Exception;

	 /**
     * A member was idle
     * @param member Member - the member that was removed
	 * @throws Exception 
     * @since 1.0
     */
	void memberIdle(InterceptorEntity nextEntity, Channel channel, Member source,
			IdleStatus status) throws Exception;
	
	void exceptionCaught(InterceptorEntity nextEntity, Channel channel, Member source,
			Throwable cause);

	void dataReceived(InterceptorEntity nextEntity, Channel channel, Member sender, Object data) throws Exception;

	void dataSent(InterceptorEntity nextEntity, Channel channel, Member target, Object data) throws Exception;

	void dataNotSent(InterceptorEntity nextEntity, Channel channel, Member target, Object data) throws Exception;

}